// 认证路由守卫
// @/utils/authGuard.ts

import { ref } from 'vue'
import type { Ref } from 'vue'
import { useAuthStore } from '../stores/modules/auth'
import type { AuthStore } from '../stores/modules/auth'

interface RouteOptions {
  url: string
  type?: 'navigateTo' | 'redirectTo' | 'reLaunch' | 'switchTab'
  params?: Record<string, any>
}

interface GuardOptions {
  requireAuth?: boolean
  requirePermissions?: string[]
  requireRoles?: string[]
  requireAny?: boolean // 是否满足任一权限即可
  fallback?: string // 权限不足时的跳转页面
  beforeEnter?: (authStore: AuthStore) => boolean | Promise<boolean>
}

export class AuthGuard {
  private static instance: AuthGuard | null = null
  private authStore: AuthStore
  private readonly loginPage = '/pages/login/login'
  private readonly unauthorizedPage = '/pages/error/403'
  private readonly whiteList: string[] = [
    '/pages/login/login',
    '/pages/register/register',
    '/pages/error/403',
    '/pages/error/404'
  ]

  private constructor() {
    this.authStore = useAuthStore()
  }

  // 获取单例实例
  static getInstance(): AuthGuard {
    if (!AuthGuard.instance) {
      AuthGuard.instance = new AuthGuard()
    }
    return AuthGuard.instance
  }

  // 路由跳转守卫
  async navigateTo(route: RouteOptions, options?: GuardOptions): Promise<void> {
    const canAccess = await this.checkAccess(route.url, options)
    
    if (!canAccess) {
      return
    }

    this.doNavigate(route)
  }

  // 检查访问权限
  private async checkAccess(url: string, options?: GuardOptions): Promise<boolean> {
    // 白名单直接放行
    if (this.isWhitelisted(url)) {
      return true
    }

    // 默认需要登录
    const requireAuth = options?.requireAuth ?? true

    // 检查登录状态
    if (requireAuth && !this.authStore.isLoggedIn) {
      await this.handleUnauthorized(url)
      return false
    }

    // 检查自定义守卫
    if (options?.beforeEnter) {
      try {
        const canEnter = await options.beforeEnter(this.authStore)
        if (!canEnter) {
          this.handleForbidden(options.fallback)
          return false
        }
      } catch (error) {
        console.error('路由守卫执行失败:', error)
        return false
      }
    }

    // 检查权限
    if (options?.requirePermissions?.length) {
      const hasPermission = options.requireAny
        ? this.authStore.hasAnyPermission(...options.requirePermissions)
        : this.authStore.hasAllPermissions(...options.requirePermissions)

      if (!hasPermission) {
        this.handleForbidden(options.fallback)
        return false
      }
    }

    // 检查角色
    if (options?.requireRoles?.length) {
      const hasRole = options.requireRoles.some(role => 
        this.authStore.hasRole(role)
      )

      if (!hasRole) {
        this.handleForbidden(options.fallback)
        return false
      }
    }

    return true
  }

  // 处理未登录
  private async handleUnauthorized(targetUrl: string): Promise<void> {
    // 保存目标页面，登录后跳转
    uni.setStorageSync('auth_redirect_url', targetUrl)
    
    uni.showToast({
      title: '请先登录',
      icon: 'none',
      duration: 1500
    })

    setTimeout(() => {
      uni.reLaunch({
        url: this.loginPage
      })
    }, 1500)
  }

  // 处理权限不足
  private handleForbidden(fallback?: string): void {
    uni.showToast({
      title: '权限不足',
      icon: 'none',
      duration: 1500
    })

    if (fallback) {
      setTimeout(() => {
        uni.navigateTo({
          url: fallback
        })
      }, 1500)
    } else {
      setTimeout(() => {
        uni.navigateBack()
      }, 1500)
    }
  }

  // 执行导航
  private doNavigate(route: RouteOptions): void {
    const { url, type = 'navigateTo', params } = route
    
    // 构建完整 URL
    let fullUrl = url
    if (params) {
      const queryString = Object.entries(params)
        .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
        .join('&')
      fullUrl += (url.includes('?') ? '&' : '?') + queryString
    }

    // 执行跳转
    const navigateMethod = uni[type] as (options: any) => void
    navigateMethod({
      url: fullUrl,
      fail: (error: any) => {
        console.error('路由跳转失败:', error)
        uni.showToast({
          title: '页面跳转失败',
          icon: 'none'
        })
      }
    })
  }

  // 检查是否在白名单
  private isWhitelisted(url: string): boolean {
    const path = url.split('?')[0]
    return this.whiteList.includes(path)
  }

  // 添加白名单
  addWhiteList(...urls: string[]): void {
    this.whiteList.push(...urls)
  }

  // 移除白名单
  removeWhiteList(url: string): void {
    const index = this.whiteList.indexOf(url)
    if (index > -1) {
      this.whiteList.splice(index, 1)
    }
  }

  // 创建路由方法
  createRoute(defaultOptions: GuardOptions) {
    return (route: RouteOptions, overrideOptions?: GuardOptions) => {
      return this.navigateTo(route, { ...defaultOptions, ...overrideOptions })
    }
  }

  // 便捷方法：需要管理员权限的路由
  adminRoute(route: RouteOptions): Promise<void> {
    return this.navigateTo(route, {
      requireRoles: ['admin']
    })
  }

  // 便捷方法：需要特定权限的路由
  permissionRoute(route: RouteOptions, permissions: string[]): Promise<void> {
    return this.navigateTo(route, {
      requirePermissions: permissions
    })
  }

  // 全局路由拦截器
  setupInterceptor(): void {
    const methods: Array<'navigateTo' | 'redirectTo' | 'reLaunch' | 'switchTab'> = [
      'navigateTo',
      'redirectTo',
      'reLaunch',
      'switchTab'
    ]

    methods.forEach(method => {
      uni.addInterceptor(method, {
        invoke: async (args) => {
          const url = args.url
          if (!url) return true

          // 检查是否需要拦截
          const needIntercept = !this.isWhitelisted(url)
          
          if (needIntercept && !this.authStore.isLoggedIn) {
            this.handleUnauthorized(url)
            return false
          }

          return true
        }
      })
    })
  }

  // 移除拦截器
  removeInterceptor(): void {
    const methods: Array<'navigateTo' | 'redirectTo' | 'reLaunch' | 'switchTab'> = [
      'navigateTo',
      'redirectTo',
      'reLaunch',
      'switchTab'
    ]

    methods.forEach(method => {
      uni.removeInterceptor(method)
    })
  }
}

// 导出单例
export const authGuard = AuthGuard.getInstance()

// 导出便捷方法
export const navigateTo = (route: RouteOptions, options?: GuardOptions) => 
  authGuard.navigateTo(route, options)

export const adminRoute = (route: RouteOptions) => 
  authGuard.adminRoute(route)

export const permissionRoute = (route: RouteOptions, permissions: string[]) => 
  authGuard.permissionRoute(route, permissions)

// 使用示例：
// import { navigateTo, adminRoute, authGuard } from '@/utils/authGuard'
//
// // 基础用法
// navigateTo({
//   url: '/pages/user/profile'
// })
//
// // 需要特定权限
// navigateTo({
//   url: '/pages/admin/users',
//   type: 'navigateTo'
// }, {
//   requirePermissions: ['user:list', 'user:view'],
//   requireAny: true
// })
//
// // 管理员路由
// adminRoute({
//   url: '/pages/admin/settings'
// })
//
// // 自定义守卫
// navigateTo({
//   url: '/pages/vip/content'
// }, {
//   beforeEnter: async (authStore) => {
//     const userInfo = authStore.userInfo
//     return userInfo?.vipLevel > 0
//   },
//   fallback: '/pages/vip/upgrade'
// })
//
// // 在 App.vue 中启用全局拦截
// authGuard.setupInterceptor() 